/// 数据合并策略
///
/// 处理多层级数据的合并和覆盖逻辑
use std::collections::HashMap;
use std::hash::Hash;

/// 合并结果
#[derive(Debug)]
pub struct MergeResult<T> {
    /// 合并后的数据
    pub data: Vec<T>,

    /// 合并统计
    pub stats: MergeStats,
}

/// 合并统计信息
#[derive(Debug, Default)]
pub struct MergeStats {
    /// 总记录数
    pub total_records: usize,

    /// 各层级记录数
    pub level_counts: HashMap<String, usize>,

    /// 覆盖记录数
    pub overridden_count: usize,

    /// 新增记录数
    pub new_count: usize,
}

/// 数据合并策略
pub trait DataMergeStrategy<T> {
    /// 获取记录的唯一标识
    fn get_key(
        &self,
        item: &T,
    ) -> String;

    /// 合并多层级数据
    fn merge(
        &self,
        levels: Vec<(String, Vec<T>)>,
    ) -> MergeResult<T>;

    /// 判断是否应该覆盖
    fn should_override(
        &self,
        _existing: &T,
        _new: &T,
    ) -> bool {
        true // 默认总是覆盖
    }
}

/// 默认合并策略
///
/// 下级数据覆盖上级数据,基于唯一键去重
pub struct DefaultMergeStrategy<T, F>
where
    F: Fn(&T) -> String,
{
    key_extractor: F,
    _phantom: std::marker::PhantomData<T>,
}

impl<T, F> DefaultMergeStrategy<T, F>
where
    F: Fn(&T) -> String,
{
    pub fn new(key_extractor: F) -> Self {
        Self { key_extractor, _phantom: std::marker::PhantomData }
    }
}

impl<T, F> DataMergeStrategy<T> for DefaultMergeStrategy<T, F>
where
    T: Clone,
    F: Fn(&T) -> String,
{
    fn get_key(
        &self,
        item: &T,
    ) -> String {
        (self.key_extractor)(item)
    }

    fn merge(
        &self,
        levels: Vec<(String, Vec<T>)>,
    ) -> MergeResult<T> {
        let mut merged: HashMap<String, (T, String)> = HashMap::new();
        let mut stats = MergeStats::default();

        // 从最上级到最下级遍历(反向),这样下级会覆盖上级
        for (region_code, items) in levels.iter().rev() {
            let level_count = items.len();
            stats.level_counts.insert(region_code.clone(), level_count);

            for item in items {
                let key = self.get_key(item);

                if let Some((existing, _)) = merged.get(&key) {
                    // 检查是否应该覆盖
                    if self.should_override(existing, item) {
                        merged.insert(key, (item.clone(), region_code.clone()));
                        stats.overridden_count += 1;
                    }
                } else {
                    // 新记录
                    merged.insert(key, (item.clone(), region_code.clone()));
                    stats.new_count += 1;
                }
            }
        }

        let data: Vec<T> = merged.into_values().map(|(item, _)| item).collect();
        stats.total_records = data.len();

        MergeResult { data, stats }
    }
}

/// 追加合并策略
///
/// 不去重,简单追加所有层级的数据
pub struct AppendMergeStrategy<T> {
    _phantom: std::marker::PhantomData<T>,
}

impl<T> AppendMergeStrategy<T> {
    pub fn new() -> Self {
        Self { _phantom: std::marker::PhantomData }
    }
}

impl<T> Default for AppendMergeStrategy<T> {
    fn default() -> Self {
        Self::new()
    }
}

impl<T: Clone> DataMergeStrategy<T> for AppendMergeStrategy<T> {
    fn get_key(
        &self,
        _item: &T,
    ) -> String {
        // 追加策略不需要键
        String::new()
    }

    fn merge(
        &self,
        levels: Vec<(String, Vec<T>)>,
    ) -> MergeResult<T> {
        let mut data = Vec::new();
        let mut stats = MergeStats::default();

        for (region_code, items) in levels {
            let count = items.len();
            stats.level_counts.insert(region_code, count);
            stats.new_count += count;
            data.extend(items);
        }

        stats.total_records = data.len();

        MergeResult { data, stats }
    }
}

/// 自定义合并策略构建器
pub struct MergeStrategyBuilder<T> {
    key_extractor: Option<Box<dyn Fn(&T) -> String + Send + Sync>>,
    override_checker: Option<Box<dyn Fn(&T, &T) -> bool + Send + Sync>>,
}

impl<T> MergeStrategyBuilder<T> {
    pub fn new() -> Self {
        Self { key_extractor: None, override_checker: None }
    }

    pub fn with_key_extractor<F>(
        mut self,
        extractor: F,
    ) -> Self
    where
        F: Fn(&T) -> String + Send + Sync + 'static,
    {
        self.key_extractor = Some(Box::new(extractor));
        self
    }

    pub fn with_override_checker<F>(
        mut self,
        checker: F,
    ) -> Self
    where
        F: Fn(&T, &T) -> bool + Send + Sync + 'static,
    {
        self.override_checker = Some(Box::new(checker));
        self
    }
}

impl<T> Default for MergeStrategyBuilder<T> {
    fn default() -> Self {
        Self::new()
    }
}

/// 合并辅助函数
pub fn merge_by_key<T, K, F>(
    levels: Vec<(String, Vec<T>)>,
    key_fn: F,
) -> MergeResult<T>
where
    T: Clone,
    K: Eq + Hash,
    F: Fn(&T) -> K,
{
    let mut merged: HashMap<K, (T, String)> = HashMap::new();
    let mut stats = MergeStats::default();

    // 从最上级到最下级遍历(反向)
    for (region_code, items) in levels.iter().rev() {
        let level_count = items.len();
        stats.level_counts.insert(region_code.clone(), level_count);

        for item in items {
            let key = key_fn(item);

            if merged.contains_key(&key) {
                merged.insert(key, (item.clone(), region_code.clone()));
                stats.overridden_count += 1;
            } else {
                merged.insert(key, (item.clone(), region_code.clone()));
                stats.new_count += 1;
            }
        }
    }

    let data: Vec<T> = merged.into_values().map(|(item, _)| item).collect();
    stats.total_records = data.len();

    MergeResult { data, stats }
}

/// 简单追加合并
pub fn merge_append<T: Clone>(levels: Vec<(String, Vec<T>)>) -> MergeResult<T> {
    let mut data = Vec::new();
    let mut stats = MergeStats::default();

    for (region_code, items) in levels {
        let count = items.len();
        stats.level_counts.insert(region_code, count);
        stats.new_count += count;
        data.extend(items);
    }

    stats.total_records = data.len();

    MergeResult { data, stats }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[derive(Debug, Clone, PartialEq)]
    struct TestData {
        id: String,
        value: i32,
    }

    #[test]
    fn test_default_merge_strategy() {
        let strategy = DefaultMergeStrategy::new(|item: &TestData| item.id.clone());

        let level1 = vec![TestData { id: "1".to_string(), value: 10 }, TestData { id: "2".to_string(), value: 20 }];

        let level2 = vec![
            TestData { id: "1".to_string(), value: 100 }, // 覆盖level1的id=1
            TestData { id: "3".to_string(), value: 30 },
        ];

        let levels = vec![("610000".to_string(), level1), ("610100".to_string(), level2)];

        let result = strategy.merge(levels);

        assert_eq!(result.data.len(), 3); // 去重后3条
        assert_eq!(result.stats.overridden_count, 1); // 1条被覆盖
        assert_eq!(result.stats.new_count, 2); // 2条新增
    }

    #[test]
    fn test_append_merge_strategy() {
        let strategy = AppendMergeStrategy::<TestData>::new();

        let level1 = vec![TestData { id: "1".to_string(), value: 10 }];

        let level2 = vec![TestData { id: "1".to_string(), value: 100 }];

        let levels = vec![("610000".to_string(), level1), ("610100".to_string(), level2)];

        let result = strategy.merge(levels);

        assert_eq!(result.data.len(), 2); // 不去重,2条
        assert_eq!(result.stats.new_count, 2);
    }
}
